home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / 24bit.c next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  7.8 KB  |  365 lines

  1. /* 
  2.  * This version of 24bit.c has been heavily modified by
  3.  * Magnus Heldestat <Magnus.Heldestad@cs.umu.se> to optimize
  4.  * for speed.  Thanks, Magnus!
  5.  */
  6.  
  7. /*
  8.  * Copyright (c) 1992 The Regents of the University of California.
  9.  * All rights reserved.
  10.  * 
  11.  * Permission to use, copy, modify, and distribute this software and its
  12.  * documentation for any purpose, without fee, and without written agreement is
  13.  * hereby granted, provided that the above copyright notice and the following
  14.  * two paragraphs appear in all copies of this software.
  15.  * 
  16.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  17.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  18.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  19.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20.  * 
  21.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  22.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  23.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  24.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  25.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  26.  */
  27.  
  28. #include <config.h>
  29. #include "video.h"
  30. #include "dither.h"
  31. #include "proto.h"
  32. #include <time.h>
  33.  
  34. /*
  35.     Optimization defines
  36.  
  37.     SAVE_L        Save L between eacn pixel
  38.     SAVE_CR        Save CR and CB netween each y iter
  39.     SAVE_ALL    SAVE_L + SAVE_CR + Save last L for the first L
  40.     POOR_Q1        Fast, but yields lower quality 
  41.     POOR_Q2        SAVE_ALL + Fast, but yields lower quality 
  42.     PRE_CALC    Precalculates the YCrCb to RGB values (in InitColorDither)
  43.     FLIP        Flips the image in the correct way for lrectwrite (gl)
  44. */
  45.  
  46. #define SAVE_ALL   /* SAVE_L and SAVE_CR automatically turned on */
  47. #define PRE_CALC
  48. #undef FLIP
  49. #undef POOR_Q1
  50. #undef POOR_Q2
  51.  
  52. /* Benchmarking for the above defines for 20 * LiftOff.mpg (in secs)
  53.    Hardware: Indy R4400 (150 MHz) with 64 meg memory running Irix 5.2
  54.    Compiler options: -kpicopt -O2 -mips2
  55.   
  56.    Name            User     Sys    Real   Func only
  57.    ====            ====     ===    ====   =========
  58.    unopt version: 108.941  1.055  1:50.98   50.59
  59.    ALL UNDEFINED: 106.254  1.098  1:50.12   38.99
  60.    SAVE_CR:       92.287   1.118  1:37.13   34.29
  61.    only PRE_CALC: 91.871   1.021  1:33.72   33.54
  62.    SAVE_L:        86.844   1.038  1:28.68   28.80
  63.    SAVE_ALL:      85.385   0.866  1:26.96   27.25
  64.    POOR_Q1:       76.498   0.905  1:18.04   18.41
  65.    POOR_Q2:       76.645   0.914  1:18.37   18.37
  66.  
  67.    NOTE 1: the unopt version is the same as in mpeg_lib-1.1
  68.    NOTE 2: PRE_CALC is defined in all except ALL UNDEFINED
  69.    NOTE 3: LiftOff is a Alias demo movie (see www.alias.com)
  70.  
  71.    As can be seen, the ColorDitherImage runs almost twice as fast with
  72.    SAVE_ALL and PRE_CALC defined  compared with the unopt version.
  73.  */
  74.  
  75.  
  76. /*
  77.  * We'll define the "ConvertColor" macro here to do fixed point arithmetic
  78.  * that'll convert from YCrCb to RGB using:
  79.  *    R = L + 1.40200*Cr;
  80.  *    G = L - 0.34414*Cb - 0.71414*Cr
  81.  *    B = L + 1.77200*Cb;
  82.  *
  83.  * We'll use fixed point by adding two extra bits after the decimal.
  84.  */
  85.  
  86. #define BITS         8
  87. #define ONE          ((int) 1)
  88. #define CONST_SCALE  (ONE << BITS)
  89. #define ALIGN(x,s) (((x & 0xff) == x) ? (x << s) : ((x < 0) ? 0 : (255 << s)))
  90. #define RR(x)      (ALIGN(x, 0))
  91. #define GG(x)      (ALIGN(x, (BITS)))
  92. #define BB(x)      (ALIGN(x, (BITS*2)))
  93.  
  94. /* Macro to convert a float to a fixed */
  95. #define FIX(x)      ((int) ((x)*CONST_SCALE + 0.5))
  96. #define FIX2(x,v)    (FIX(x) * (v - 128))
  97.  
  98. /* Turn on SAVE_ALL if POOR_Q2 */
  99. #ifdef POOR_Q2
  100. #ifndef SAVE_ALL
  101. #define SAVE_ALL
  102. #endif
  103. #endif
  104.  
  105. /* SAVE_ALL implies SAVE_L and SAVE_CR */
  106. #ifdef SAVE_ALL
  107. #ifndef SAVE_L
  108. #define SAVE_L
  109. #endif
  110. #ifndef SAVE_CR
  111. #define SAVE_CR
  112. #endif
  113. #endif
  114.  
  115. /* If POOR_Q?, simplify the ALIGN define */
  116. #ifdef POOR_Q1
  117. #undef ALIGN
  118. #define ALIGN(x,s)  (x << s)
  119. #endif
  120. #ifdef POOR_Q2
  121. #undef ALIGN
  122. #define ALIGN(x,s)  (x << s)
  123. #endif
  124.  
  125. #ifdef PRE_CALC
  126. static int *Cb_r_tab, *Cr_g_tab, *Cb_g_tab, *Cr_b_tab;
  127. #endif
  128.  
  129. /*
  130.  *--------------------------------------------------------------
  131.  *
  132.  * InitColorDither --
  133.  *
  134.  *    To get rid of the multiply and other conversions in color
  135.  *    dither, we use a lookup table.
  136.  *
  137.  * Results:
  138.  *    None.
  139.  *
  140.  * Side effects:
  141.  *    The lookup tables are initialized.
  142.  *
  143.  *--------------------------------------------------------------
  144.  */
  145.  
  146. void
  147. InitColorDither()
  148. {
  149. #ifdef PRE_CALC
  150.     int CR, CB, i;
  151.  
  152.     Cr_b_tab = (int *)malloc(256*sizeof(int));
  153.     Cr_g_tab = (int *)malloc(256*sizeof(int));
  154.     Cb_g_tab = (int *)malloc(256*sizeof(int));
  155.     Cb_r_tab = (int *)malloc(256*sizeof(int));
  156.  
  157.     for (i=0; i<256; i++) {
  158.     CB = CR = i;
  159.  
  160.     CB -= 128; CR -= 128;
  161.  
  162.     Cb_r_tab[i] = FIX(1.40200) * CB;
  163.     Cr_g_tab[i] = -FIX(0.34414) * CR;
  164.     Cb_g_tab[i] = -FIX(0.71414) * CB;   
  165.     Cr_b_tab[i] = FIX(1.77200) * CR;
  166.  
  167.     Cb_r_tab[i] >>= BITS;
  168.     Cr_g_tab[i] >>= BITS;
  169.     Cb_g_tab[i] >>= BITS;
  170.     Cr_b_tab[i] >>= BITS;
  171.     }
  172. #endif
  173. }
  174.  
  175.  
  176.  
  177. /* Space saving define */
  178. #define RR_GG_BB\
  179.     R = L + cb_r;\
  180.     G = L + cr_cb;\
  181.     B = L + cr_b;\
  182.     r = RR(R);\
  183.     g = GG(G);\
  184.     b = BB(B);
  185.  
  186. /*
  187.  *--------------------------------------------------------------
  188.  *
  189.  * ColorDitherImage --
  190.  *
  191.  *    Converts image into 24 bit color.
  192.  *
  193.  * Results:
  194.  *    None.
  195.  *
  196.  * Side effects:
  197.  *    None.
  198.  *
  199.  *--------------------------------------------------------------
  200.  */
  201. void
  202. ColorDitherImage(lum, cr, cb, out, rows, cols)
  203.   unsigned char *lum;
  204.   unsigned char *cr;
  205.   unsigned char *cb;
  206.   unsigned char *out;
  207.   int cols, rows;
  208.  
  209. {
  210.     int L, CR, CB;
  211.     unsigned int *row1, *row2;
  212.     unsigned char *lum2;
  213.     int x, y;
  214.     unsigned int r, b, g;
  215.     int cb_r, cr_b, cr_cb;
  216. #ifndef PRE_CALC
  217.     int t1, t2;
  218. #endif
  219. #ifdef SAVE_L
  220.     int rgb;
  221.     int LL;
  222. #endif
  223. #ifdef SAVE_CR
  224.     int ccr=-1, ccb=-1;
  225. #endif
  226.  
  227. #ifdef FLIP
  228.     row1 = (unsigned int *)out + cols * (rows - 1);
  229.     row2 = row1 - cols;
  230. #else
  231.     row1 = (unsigned int *)out;
  232.     row2 = row1 + cols;
  233. #endif
  234.     lum2 = lum + cols;
  235.  
  236.     for (y=0; y<rows; y+=2) {
  237.     for (x=0; x<cols; x+=2) {
  238.         int R, G, B;
  239.  
  240.         CR = *cr++;
  241.         CB = *cb++;
  242. #ifdef SAVE_CR
  243.         if(ccr != CR || ccb != CB) {
  244. #ifdef PRE_CALC
  245.         cb_r = Cb_r_tab[CB];                            
  246.         cr_b = Cr_b_tab[CR];
  247.         cr_cb = Cr_g_tab[CR] + Cb_g_tab[CB];
  248. #else
  249.         cb_r = FIX2(1.40200, CB);
  250.         cr_b = FIX2(1.77200, CR);
  251.         t1 = -FIX2(0.34414, CR);
  252.         t2 = -FIX2(0.71414, CB);
  253.         cb_r >>= BITS;
  254.         cr_b >>= BITS;
  255.         t1 >>= BITS;
  256.         t2 >>= BITS;
  257.         cr_cb = t1 + t2;
  258. #endif
  259.         ccr = CR;
  260.         ccb = CB;
  261. #ifdef SAVE_ALL
  262.         LL = -1;
  263. #endif
  264.         }
  265. #else
  266. #ifdef PRE_CALC
  267.         cb_r = Cb_r_tab[CB];
  268.         cr_b = Cr_b_tab[CR];
  269.         cr_cb = Cr_g_tab[CR] + Cb_g_tab[CB];
  270. #else
  271.         cb_r = FIX2(1.40200, CB);
  272.         cr_b = FIX2(1.77200, CR);
  273.         t1 = -FIX2(0.34414, CR);
  274.         t2 = -FIX2(0.71414, CB);
  275.         cb_r >>= BITS;
  276.         cr_b >>= BITS;
  277.         t1 >>= BITS;
  278.         t2 >>= BITS;
  279.         cr_cb = t1 + t2;
  280. #endif   /* PRE_CALC */
  281. #endif   /* SAVE_CR  */
  282.  
  283. #ifdef SAVE_L
  284. #ifdef SAVE_ALL
  285.             L = *lum++;
  286.             if(L != LL) {
  287.                 RR_GG_BB
  288.                 rgb = r | g | b;
  289.                 LL = L;
  290.             }
  291.             *row1++ = rgb;
  292. #else
  293.         LL = L = *lum++;
  294.         RR_GG_BB
  295.         rgb = *row1++ = r | g | b;
  296. #endif
  297. #else
  298.         L = *lum++;
  299.         RR_GG_BB
  300.         *row1++ = r | g | b;
  301. #endif
  302.  
  303.  
  304.  
  305.         L = *lum++;
  306. #ifdef SAVE_L
  307.         if(L != LL) {
  308.         RR_GG_BB
  309.         rgb = r | g | b;
  310.         LL = L;
  311.         } 
  312.         *row1++ = rgb;
  313. #else
  314.         RR_GG_BB
  315.             *row1++ = r | g | b;
  316. #endif
  317.  
  318.  
  319.  
  320.         L = *lum2++;
  321. #ifdef SAVE_L
  322.         if(L != LL) {
  323.         RR_GG_BB
  324.         rgb = r | g | b;
  325.         LL = L;
  326.         } 
  327.         *row2++ = rgb;
  328. #else
  329.         RR_GG_BB
  330.             *row2++ = r | g | b;
  331. #endif
  332.  
  333.  
  334.  
  335.         L = *lum2++;
  336. #ifdef SAVE_L
  337.         if(L != LL) {
  338.         RR_GG_BB
  339.         rgb = r | g | b;
  340. #ifdef SAVE_ALL
  341.         LL = L;
  342. #endif
  343.         } 
  344.         *row2++ = rgb;
  345. #else
  346.         RR_GG_BB
  347.             *row2++ = r | g | b;
  348. #endif
  349.  
  350.  
  351.  
  352.     }
  353.     lum += cols;
  354.     lum2 += cols;
  355. #ifdef FLIP
  356.     row1 -= 3 * cols;
  357.     row2 -= 3 * cols;
  358. #else
  359.         row1 += cols;
  360.         row2 += cols;
  361. #endif
  362.     }
  363. }
  364.  
  365.